package fundation.generics;

import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 类型擦除
 */
public class TypeErasure {


    /**
     * 测试桥方法
     * 桥接方法 blog https://blog.csdn.net/z69183787/article/details/81115524?tdsourcetag=s_pcqq_aiomsg
     * 官方文档 https://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html
     * 泛型 当子类在继承时指明类型，子类继承父类的所有方法，此时子类的 public void setData(Integer data)方法
     *  和父类的 public void setData(Object data) 方法签名不一样，为了向前兼容，所以编译的时候会自动在子类生成
     *  public void setData(Object data) 这个方法。
     */
    @Test
    public void testBridgeMethods(){
        MyNode mn = new MyNode(5);
        Node n = mn;            // A raw type - compiler throws an unchecked warning
        n.setData("Hello");
//        Integer x = mn.data;    // Causes a ClassCastException to be thrown.
    }
    public class Node {

        public Object data;

        public Node(Object data) { this.data = data; }

        public void setData(Object data) {
            System.out.println("Node.setData");
            this.data = data;
        }
    }

    public class MyNode extends Node {
        public MyNode(Integer data) { super(data); }

        // Bridge method generated by the compiler
        // 桥方法，override 重写父方法 编译时自动生成
//        public void setData(Object data) {
//            setData((Integer) data);
//        }
        /**
         * 这个方法没有重写父方法和父方法并存
         * @param data
         */
        public void setData(Integer data) {
            System.out.println("MyNode.setData");
            super.setData(data);
        }
    }


    /**
     * 反射获取桥方法
     * 给Integer数组增加String字符串
     */
    public void testBridgeMethodsReflect() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        Method method  = list.getClass().getMethod("add", Object.class);
        method.invoke(list, "aaaa");
    }
}
